% \iffalse meta-comment
% Copyright (C) 2006-2007 by Martin Scharrer <martin@scharrer-online.de>
% http://www.scharrer-online.de/latex/
% -----------------------------------------------------------------
% 
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3
% of this license or (at your option) any later version.
% The latest version of this license is in
%   http://www.latex-project.org/lppl.txt
% and version 1.3 or later is part of all distributions of LaTeX
% version 2005/12/01 or later.
% 
% This work has the LPPL maintenance status `maintained'.
% 
% The Current Maintainer of this work is Martin Scharrer.
% 
% This work consists of the files svn-multi.dtx and svn-multi.ins
% and the derived files svn-multi.sty and svnkw.sty.
% $Id: svn-multi.dtx 628 2007-07-10 20:32:06Z martin $
% \fi
% \iffalse
%<*driver>
\ProvidesFile{svn-multi.dtx}
%</driver>
%<package>%% DTX Id: $Id: svn-multi.dtx 628 2007-07-10 20:32:06Z martin $
%<package>\NeedsTeXFormat{LaTeX2e}[1999/12/01]
%<package>\ProvidesPackage{svn-multi}
%<*package|driver>
    [2007/07/10 v1.3a SVN Keywords for multi-file LaTeX documents]
%</package|driver>
%<wrapper>\NeedsTeXFormat{LaTeX2e}[1999/12/01]
%<wrapper>\ProvidesPackage{svnkw}
%<wrapper> [2007/07/10 v1.3a Backward compatibility wrapper for svn-multi]
%<wrapper>\RequirePackage{svn-multi}[2007/07/10]
%
%<*driver>
\documentclass{ltxdoc}
\usepackage{svn-multi}
\usepackage{ifpdf}
\ifpdf
    % use hypdoc if you have it, hyperref else
    %\usepackage[hyperfootnotes=false]{hyperref}
    \usepackage{hypdoc}
\else\let\url=\texttt\fi
\usepackage{xspace}
\newcommand{\ie}{i.e.\@\xspace}
\newcommand{\eg}{e.g.\@\xspace}

\iffalse % crossreference of macros in documentation
\begingroup
\catcode`\*=0
\catcode`\\=12
*gdef*removeslash\#1 #2END{#1#2}
*endgroup

\makeatletter
 % link \cs to macro definitions
 \let\origmacro\macro
 \let\origendmacro\endmacro
 \let\origStopEventually\StopEventually
 \let\origPrintDescribeMacro\PrintDescribeMacro

 \renewenvironment{macro}[1]{%
  \edef\macroname{\expandafter\removeslash\detokenize{#1}END}
  \hypertarget{\macroname}{}
  \origmacro#1}
  {\origendmacro}
 
  \DeclareRobustCommand{\cs}[1]{\hyperlink{Desc@#1}{\texttt{\textbackslash#1}}}

 \def\StopEventually#1{\origStopEventually{#1}%
 \DeclareRobustCommand{\cs}[1]{\hyperlink{##1}{\texttt{\textbackslash##1}}}
 }

 \def\PrintDescribeMacro#1{%
  \edef\macroname{\expandafter\removeslash\detokenize{#1}END}%
  \raisebox{11pt}[11pt]{\hypertarget{Desc@\macroname}{}}
  \origPrintDescribeMacro{#1}
 }
\fi

\EnableCrossrefs
%\DisableCrossrefs
\CodelineIndex
%\PageIndex
\RecordChanges
%\OnlyDescription
\begin{document}
  \DocInput{svn-multi.dtx}
  \PrintChanges
  \PrintIndex
\end{document}
%</driver>
%<*package>
% \fi
%
% \CheckSum{573}
%
% {\makeatother
% \CharacterTable
%  {Upper-case    \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
%   Lower-case    \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
%   Digits        \0\1\2\3\4\5\6\7\8\9
%   Exclamation   \!     Double quote  \"     Hash (number) \#
%   Dollar        \$     Percent       \%     Ampersand     \&
%   Acute accent  \'     Left paren    \(     Right paren   \)
%   Asterisk      \*     Plus          \+     Comma         \,
%   Minus         \-     Point         \.     Solidus       \/
%   Colon         \:     Semicolon     \;     Less than     \<
%   Equals        \=     Greater than  \>     Question mark \?
%   Commercial at \@     Left bracket  \[     Backslash     \\
%   Right bracket \]     Circumflex    \^     Underscore    \_
%   Grave accent  \`     Left brace    \{     Vertical bar  \|
%   Right brace   \}     Tilde         \~}
% }
% \changes{v1.0}{2006/05/27}{Initial version}
% \changes{v1.1}{2006/06/08}{Added macros to extract and typeset date/time
% informations. Added macros to set and typeset main URL or filename.}
% \changes{v1.2}{2007/06/22}{Renamed packet from \texttt{svnkw} to
% \texttt{svn-multi} to match CTAN directory. Wrapper file
% \texttt{svnkw.sty} is provided for backward compatibility.}
% \changes{v1.3}{2007/07/01}{Added verbatim support. Keywords can now contain
% special character like \texttt{\_ \^{} \$ \% \& \textbackslash}. Rewrote
% keyword check macros to work with verbatim code. \texttt{\textbackslash
% nofiles} is now obeyed.}
% \changes{v1.3a}{2007/07/10}{Fixed issue with unwanted spaces generated by
% \cs{svnid}, \cs{svnidlong} and \cs{svnkwsave}, \eg when used in a file which is
% included with \cs{input}}
%
% \GetFileInfo{svn-multi.sty}
%
% \DoNotIndex{\newcommand,\newenvironment,\AtBeginDocument,\AtEndDocument}
% \DoNotIndex{\def,\let,\edef,\xdef,\item,\space,\write,\jobname,\relax,\!}
% \DoNotIndex{\closeout,\csname,\DeclareRobustCommand,\else,\empty,\newwrite}
% \DoNotIndex{\endcsname,\expandafter,\fi,\Hurl,\hyper@normalise,\@ifnextchar}
% \DoNotIndex{\ifnum,\@ifundefined,\ifx,\immediate,\InputIfFileExists,\ }
% \DoNotIndex{\newcount,\noexpand,\openout,\PackageWarning,\@percentchar}
% \DoNotIndex{\@sanitize,\@makeother,\@iwsvn,\%,\_,\&,\^,\$,\#,\ ,\\,\if@filesw}
% \DoNotIndex{\gdef,\begingroup,\endgroup,\catcode}
%
%
% \title{The \textsf{svn-multi} package\thanks{This document
%   corresponds to \textsf{svn-multi}~\fileversion, dated \filedate.}
%   \\also known as \textsf{svnkw}}
% \author{Martin Scharrer \\ \url{martin@scharrer-online.de} \\
% \url{http://www.scharrer-online.de/latex/svn-multi}}
%
% \ifpdf
% \hypersetup{
%	pdfauthor={Martin Scharrer <martin@scharrer-online.de>},
%	pdftitle={The svn-multi package also known as svnkw},
%	pdfsubject={Documentation of LaTeX package svn-multi which allows the
%	typesetting of Subversion keywords in multi-file LaTeX documents},
%	pdfkeywords={svn-multi, svnkw, LaTeX, Subversion, keywords, Version
%	Control, Id}
% }
% \fi
% \maketitle
%
% \section{Package naming}
% The authors first choice for this package was |svnkw| but the CTAN
% maintainer suggested a more descriptive name and put the package in the
% |svn-multi|\footnote{CTAN:
% \url{http://www.ctan.org/tex-archive/macros/latex/contrib/svn-multi/}}
% directory. In this version the style file is renamed to |svn-multi|, but a
% |svnkw| dummy style file is still provided for backward compatibility.
%
% \section{Introduction}
% This package lets you typeset keywords of the version control system Subversion\footnote
% {Subversion homepage: \url{http://subversion.tigris.org/}} (svn), which is the successor of the popular CVS,
% inside your \LaTeX{} files anywhere you like.
% Unlike the very similar package
% |svn|\footnote{CTAN:
% \url{http://www.ctan.org/tex-archive/macros/latex/contrib/svn/}} the usage of
% multiple files for one \LaTeX{} document is well supported. The package
% acquires the keywords of the last changed file and provides them to the user
% through macros. The package has to read all keywords of all files first and
% writes the most recent values in an auxiliary file with an `.svn'
% extention. This file is read back at the next \LaTeX{} run which introduces a
% delay like by the table of contents. The standard \LaTeX{} switch |\nofiles|
% can be used to suppress the file generation. Macros to typeset the keywords 
% of the current |include|d or |input|ed \LaTeX{} file are also provided.
%
%
% \section{Usage}
%
% \subsection{Including of the Subversion keywords}
% To include your Subversion Id keywords use \cs{svnid} or \cs{svnidlong}.
% This macros should be written very
% early in each file, \ie in the preamble of the main document soon after
% |\documentclass| and |\usepackage{svn-multi}| (or, outdated,
% |\usepackage{svnkw}|) and as first in \emph{every} |\include|d
% subfile before the |\chapter| macro. They do not create any output.
% See section~\ref{sec:kwaccess} to learn how to typeset the keyword values.
%
% \DescribeMacro{\svnid}
% Macro for the svn Id keyword.
% Write the macro as |\svnid{$||Id$}| into your \LaTeX{} files. A trailing colon
% with spaces after the |Id| is also valid but \textbf{everything else} except
% a valid Subversion string will cause a \TeX{} parse error.
% Don't forget to set the subversion property |svn:keywords| of the files
% to at least `|Id|'. Subversion will expand it at the next commit.
% Please note that because the value is read verbatim the macro should exactly be
% written like above. Spaces, newlines or comments between |\svnid| and
% the \{ will lead to \TeX{} parse errors.
%
% \DescribeMacro{\svnidlong}
% Macro for a ``long Id''.
% Saves similar values like in `|Id|' but from the keywords
% |HeadURL|, |LastChangedDate|, |LastChangedRevision| and |LastChangedBy|.
% The usage of \cs{svnid} or \cs{svnidlong} is a matter of taste. The second is
% more readable inside the code and results in a nicer date and a full URL,
% not only the filename. Both can also be used together.
%
% Write this macro like this (order of arguments not meaningfull)\\[2ex]
% |\svnidlong|\\
% |{$||HeadURL$}|\\
% |{$||LastChangedDate$}|\\
% |{$||LastChangedRevision$}|\\
% |{$||LastChangedBy$}|\\[2ex]
% in your files and set the subversion
% property |svn:keywords| of them
% to\\`|HeadURL LastChangedDate LastChangedRevision LastChangedBy|'.
%
% Please note that the arguments are read verbatim. Special precaution are
% taken to allow spaces, newlines and comments direct after the |\svnidlong| 
% and after each of the four arguments, just in case someone need this.
% In fact everything not inside braces \{ \} is ignored.
%
% The two macros above are sufficient for the operation of |svn-multi| but
% the following macros are provided for additional or alternative keyword
% handling.
%
% \DescribeMacro{\svn}
% \DescribeMacro{\svn*}
% This macro let you typeset svn keywords directly. The only argument is
% the svn keyword in the usual dollars. The dollars will be stripped
% and the rest is typeset as normal text. The star version strips also the
% space before the last dollar.
% This macro alone was the very first version of |svnkw| and is still included
% for fast and simple keyword typesetting.
%
% \DescribeMacro{\svnkwsave}
% This macro lets you include and save any keyword you like. The syntax is 
% |\svnkwsave|\{\$\meta{keyword}\$\}. The keyword can be already expanded or
% not (no value and only ``|:|'' or nothing after the key name). This macro is
% also used internally and does not create any output.
% Please note that the argument is read verbatim and that there should be no
% space between the macro and the argument's left brace.
%
% \subsection{Typesetting the keyword values}\label{sec:kwaccess}
% The following macros can be used to typeset the keyword values anywhere in
% the document. Please note that note all \LaTeX{} fonts have all special
% characters, \eg `\_' is not provided in the standard roman font. To proper
% typeset filename and URL containing these letters you can use either
% texttyper font (|\texttt|) or use |{\urlstyle{rm}\svnnolinkurl{...}}| which
% needs the |hyperref| package.
%
% Like already mentioned |svn-multi| knows two groups of keywords. The first
% group contains of the keywords for the whole document which hold the values
% of the most recent committed file, the second contains of the \emph{current}
% or \emph{file local} keywords, \eg the keywords of the current file.
%
% \DescribeMacro{\svnrev}
% \DescribeMacro{\svndate}
% \DescribeMacro{\svnauthor}
% These macros hold the keyword values of the whole document, \ie of the
% most recent revision. They can be used everywhere in every file of the
% \LaTeX{} document, after |\usepackage{svn}| of course. Please see
% section~\ref{sec:date} how to typeset parts of the date.
%
% \DescribeMacro{\svnfilerev}
% \DescribeMacro{\svnfiledate}
% \DescribeMacro{\svnfileauthor}
% These macros hold the keyword values of the current \LaTeX{} file, but
% only if it contains a \cs{svnid} or \cs{svnidlong} macro. Otherwise
% the macros hold still the values of the last file. Please see
% section~\ref{sec:date} how to typeset parts of the date. See \cs{svnkw} below
% for all other keywords.
%
% \DescribeMacro{\svnmainurl}
% \DescribeMacro{\svnmainfilename}
% The macro |\svnmainurl| and |\svnmainfilename| hold the URL and the filename
% of the main \LaTeX{file} as long the keywords |HeadURL| or |Id| were used in
% it, respectively.
% These can be used to typeset this information anywhere in the document
% which might be more descriptive as the name of the current file (which can
% be typeset with |\svnkw{HeadURL}| or |\svnkw{Filename}| after \cs{svnid} or
% \cs{svnidlong}, respectively).
%
% \DescribeMacro{\svnsetmainfile}
% This will declare the current file as the main LaTeX
% file by defining the above macros. It will automatically be called at the
% end of the preamble so the user normally doesn't have to use it by him- or
% herself as long it isn't needed in the preamble. \par
% Please note that this macro changes the definition of |\svnmainurl| and
% |\svnmainfilename| directly without going over the auxiliary file. Calling
% it in several files will make this two macros inconsistent.
%
% \DescribeMacro{\svnkw}
% All keywords saved with \cs{svnid}, \cs{svnidlong} or \cs{svnkwsave} can be typeset
% by this macro which is a holdover of pare-multi-file times of this package.
% It takes one argument which must be a subversion keyword name. It
% then returns the current value of this keyword or nothing (|\relax|) when
% the keyword was not set yet.
% Examples:\\
% \indent\indent |\textsl{Revision: \svnkw{Revision}}|\\
% \indent\indent |URL: \url{\svnkw{HeadURL}}|\\
% In the second example |\url| (|hyperref| package) is used to add a
% hyperlink and to avoid problems with underscores (|_|) inside the URL.
% |svn-multi| is also providing a macro \cs{svnnolinkurl} which works like |\url|
% but doesn't adds an hyperlink. See the description of this macro for more
% details.
%
% If the given keyword doesn't exists a package warning is given to allow
% spelling errors to be tracked down. This doesn't work well when \cs{svnkw}
% is used inside |\url|. In this case the
% warning code will be typeset(!) verbatim into the document by |\url|.
%
% \DescribeMacro{\svnkwdef}
% This macro is used to define the keyword values, \ie
% \cs{svnkwdef}\marg{keyword}\marg{value}. This is normally only
% called internally but could be used by the user to override single keywords.
% The values can then be typeset by \cs{svnkw}.
% Note that this macro has no influence on the calculation of the latest
% revision.
%
% Note that for \cs{svnkw} and \cs{svnkwdef} all different names for one keyword
% are valid and result in the access of the same variable. So \eg subversion
% treats |Rev|, |Revision| and |LastChangedRev| the same way and so does this
% macros. You can \eg say |\svnkwdef{Rev}{123}| and then typeset it with
% |\svnkw{Revision}| or |\svnkw{LastChangedRev}| if you like.
%
% \subsubsection{Accessing Date Values}\label{sec:date}
% \DescribeMacro{\svnfileyear}
% \DescribeMacro{\svnfilemonth}
% \DescribeMacro{\svnfileday}
% \DescribeMacro{\svnfilehour}
% Whenever the date information is read, \ie by \cs{svnidlong}, \cs{svnid},
% |\svnkwsave{Date}| or |\svnkwsave{LastChangedDate}|, the following macros are
% set to the appropriate date parts for the current file (the |\svnfile...|
% versions) and for the whole document.
%
% \iffalse Put here and not above to avoid 'to many floats' error. \fi
% \DescribeMacro{\svnfileminute}
% \DescribeMacro{\svnfilesecond}
% \DescribeMacro{\svnfiletimezone}
% Please note that the hour and timezone are dependend on the keyword which
% defines the date informations. The hour will be in UTC aka Zulu-time, \ie
% timezone +0000, when the date comes from the |Id| keyword.
% \iffalse Put here and not above to avoid 'to many floats' error. \fi
% \DescribeMacro{\svnyear}
% \DescribeMacro{\svnmonth}
% \DescribeMacro{\svnday}
% \DescribeMacro{\svnhour}
% Otherwise the hour and timezone will be in local time.
% To avoid confusion the |Id| and |Date|/|LastChangedDate| keywords, \eg
% \cs{svnid} and \cs{svnidlong}, should not be intermixed and/or the timezone
% should always be typeset together with the time.
%
% \iffalse Put here and not above to avoid 'to many floats' error. \fi
% \DescribeMacro{\svnminute}
% \DescribeMacro{\svnsecond}
% \DescribeMacro{\svntimezone}
% Please also note that the timezone macros only hold the sign and the first
% two digits of the timezone. This is needed to define \cs{svnpdfdate}. The last
% two digits are always `00' anyway. If you need full ISO timezone write
% |\svnfiletimezone00| or |\svntimezone00|.
%
% \vspace{7ex}
%
% \DescribeMacro{\svnpdfdate}
% Returns the last changed date of the whole document in a format needed for
% |\pdfinfo|. Can be used like this:
% |\pdfinfo{ /CreationDate (D:\svnpdfdate) }|, to set the PDF creation date to
% the last changed date if you use |pdflatex| to compile your \LaTeX{} document.
%
% \subsection{Using full author names}
% If you like to have the full author\footnote{This means subversion authors,
% \eg the persons who commit changes into the svn repository.}
% names, not only the usernames, in your
% document you can use the following macros. First you have to register all
% authors of the document with \cs{svnRegisterAuthor} and then you can write
% \eg |\svnFullAuthor{\svnauthor}| or |\svnFullAuthor{\svnfileauthor}|.
%
% \DescribeMacro{\svnRegisterAuthor}
% The usage is \cs{svnRegisterAuthor}\marg{username}\marg{full name} which
% registers \meta{full name} as full name for \meta{username}.
%
% \DescribeMacro{\svnFullAuthor}
% \DescribeMacro{\svnFullAuthor*}
% Takes the username as argument and returns the full name if it was
% registered first with \cs{svnRegisterAuthor}, otherwise it returns the given
% username. The star version returns the username in parentheses after the
% full name.
%
% \subsection{Using full revision names}
% Like the author's also revision names/tags can be registered and used later.
% This macros were implemented on user request and have the drawback
% that you have to guess the next revision number of your document in order
% to get correct results when you like to tag the to-be-checked-in revision.
% Please note that this has nothing to do with the normal subversion tagging.
%
% \DescribeMacro{\svnRegisterRevision}
% The usage is \cs{svnRegisterRevision}\marg{revision number}\marg{tag name}
% which registers \meta{tag name} as tag name for \meta{revision number}.
%
% \DescribeMacro{\svnFullRevision}
% \DescribeMacro{\svnFullRevision*}
% Takes a \marg{revision number} (\ie |\svnrev|, |\svnfilerev| or a number)
% as argument and returns the full name if it was registered first with
% \cs{svnRegisterRevision}, otherwise it returns ``Revision \meta{revision
% number}''.
% The star version returns also the revision number leaded by `r' in parentheses
% after the tag name, \eg |Name (r123)|.
%
% \subsection{Verbatim URLs with and without hyperlinks}
% \DescribeMacro{\svnnolinkurl}
% This macro allows you to write |\svnnolinkurl{\svnkw{HeadURL}}| and get
% the Head URL typeset verbatim. However |\url{\svnkw{HeadURL}}| (|hyperref|
% package) gives you the same result with hyperlinked. Both macros require
% the |hyperref| package which is not automatically loaded by |svn-multi|.
% Please load it manually when you like to use \cs{svnnolinkurl}.
%
% Since v1.3 all keywords are read and typeset verbatim so this macro isn't
% this important anymore. However together with |hyperref|s |\urlstyle| macro
% it can be used to have keyword values with special characters in roman font,
% which normaly doesn't hold letters like `\_'.
%
% Please note that you can't use |hyperref|s |\nolinkurl| because it won't
% expand \cs{svnkw}.
%
% 
%
% \StopEventually{}
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \section{Implementation}
 
% \begin{macro}{\svn}
% \begin{macro}{\svn*}
% After *-testing, the intermediate macros |\svn@s| and |\svn@n| are called to
% strip the |{ }| from |\svn|[|*|]|{$...$}| and to remove the |*|. Then the
% actual macros are called to strip the dollars with or without the space
% before the last dollar.
% \changes{v1.2}{2007/06/22}{Added star version. Normal version was not
% changed to not break existing documents with user defined keywords without
% leading space.}
%    \begin{macrocode}
\newcommand{\svn}{\@ifnextchar{*}{\svn@s}{\svn@n}}
\def\svn@n#1{\@svn@n#1}
\def\svn@s*#1{\@svn@s#1}
\def\@svn@n$#1${#1}
\def\@svn@s$#1 ${#1}
%    \end{macrocode}
% \end{macro}
% \end{macro}

% \subsection{Definition of init values}
%    \begin{macrocode}
% Init values
\def\svnrev{0}      \def\svnfilerev{0}      \def\@svn@rev{0}        
\def\svndate{}      \def\svnfiledate{}      \def\@svn@date{}        
\def\svnauthor{}    \def\svnfileauthor{}    \def\@svn@author{}
\def\svnyear{0}     \def\svnfileyear{0}     \def\@svn@year{0}   
\def\svnmonth{0}    \def\svnfilemonth{0}    \def\@svn@month{0}  
\def\svnday{0}      \def\svnfileday{0}      \def\@svn@day{0}    
\def\svnhour{0}     \def\svnfilehour{0}     \def\@svn@hour{0}   
\def\svnminute{0}   \def\svnfileminute{0}   \def\@svn@minute{0} 
\def\svnsecond{0}   \def\svnfilesecond{0}   \def\@svn@second{0} 
\def\svntimezone{0} \def\svnfiletimezone{0} \def\@svn@timezone{0}   
\def\svnmainurl{NOT SET}\def\svnmainfilename{NOT SET}   
%    \end{macrocode}
%

% \subsection{Id macros}
% \subsubsection{Normal Id}
% \begin{macro}{\svnid}
% Calls \cs{svnkwsave} with |\@svnidswtrue| so that the Id keyword will be
% parsed at the end of \cs{svnkwsave}.
%    \begin{macrocode}
\newcommand*{\svnid}{%
\@svnidswtrue
\svnkwsave
} 
\newif\if@svnidsw
\@svnidswfalse
%    \end{macrocode}
% \end{macro}
%

% \begin{macro}{\svn@scanId}
% Scans svn Id (after it got parsed by \cs{svnkwsave}).
% Awaits only Id value without leading `|Id:|' and a trailing |\relax| as end
% marker.
% It calls \cs{@svn@scandate} to extract the date informations and
% \cs{@svn@updateid} to update global Id values and also sets the appropriate
% keywords.
%    \begin{macrocode}
\def\svn@scanId#1 #2 #3 #4 #5\relax{%
% #1 is filename, #2 is revision, #3 is date (JJJJ-MM-DD),
% #4 is time (HH:MM:SST), #5 is author (username)
\@svn@scandate{#3 #4}%
\@svn@updateid{#2}{#3 #4}{#5}%
\svnkwdef{Filename}{#1}%
\svnkwdef{Date}{#3 #4}%
\svnkwdef{Revision}{#2}%
\svnkwdef{Author}{#5}%
}
%    \end{macrocode}
% \end{macro}
%

% \begin{macro}{\@svn@updateid}
% We first define the expanded arguments to variables for the user.
% The expansion is needed because the arguments content is mostly generic like
% |\svn@key| and |\svn@value| which can change very soon after this macro.
%    \begin{macrocode}
\def\@svn@updateid#1#2#3{% #1 = rev, #2 date, #3 author (username)
\xdef\svnfilerev{#1}%
\xdef\svnfiledate{#2}%
\xdef\svnfileauthor{#3}%
%    \end{macrocode}
% Then we check if the revision is non-empty (not yet expanded by
% subversion?) and larger then the current maximum value |\@svn@rev|.
% If yes we save all value to save them in the .svn-file later.
%    \begin{macrocode}
\ifx\svnfilerev\empty\else
\ifnum\@svn@rev<\svnfilerev
\xdef\@svn@rev{#1}%
\xdef\@svn@date{#2}%
\xdef\@svn@author{#3}%
\xdef\@svn@year{\svnfileyear}%
\xdef\@svn@month{\svnfilemonth}%
\xdef\@svn@day{\svnfileday}%
\xdef\@svn@hour{\svnfilehour}%
\xdef\@svn@minute{\svnfileminute}%
\xdef\@svn@second{\svnfilesecond}%
\xdef\@svn@timezone{\svnfiletimezone}%
\else\fi
\fi
}
%    \end{macrocode}
% \end{macro}
%

% \subsubsection{Long Id}
% \begin{macro}{\svnidlong}
% We clear the keyword value first to reduce the risk though bad user input.
%    \begin{macrocode}
\newcommand{\svnidlong}{%
\svnkwdef{HeadURL}{}%
\svnkwdef{LastChangedDate}{}%
\svnkwdef{LastChangedRevision}{0}%
\svnkwdef{LastChangedBy}{}%
%    \end{macrocode}
% The catcodes are changed by \cs{svn@catcodes} to allow \TeX-special characters 
% inside the keywords.
% The braces \{ \} are changed to allow comments between the arguments. 
% \cs{svnidlong@readargsfull} is called to read the arguments.
%    \begin{macrocode}
\begingroup 
\svn@catcodes
\catcode`\{=12
\catcode`\}=12
\svnidlong@readargsfull
}
%    \end{macrocode}
% \end{macro}

% \begin{macro}{\svn@catcodes}
% Changes all \TeX-special character to category ``other''. The newline aka
% return is changed to category ``ignore'' so line breaks are not taken as
% part of the verbatim arguments.
%    \begin{macrocode}
\def\svn@catcodes{%
\catcode`\%=12
\catcode`\_=12
\catcode`\^=12
\catcode`\$=12
\catcode`\&=12
\catcode`\#=12
\catcode`\~=12
 %%\catcode`\ =10
\catcode`\\=12
\catcode`\^^M=9
}
%    \end{macrocode}
% \end{macro}

% \begin{macro}{\svnidlong@readargsfull}
% Reads all four arguments of \cs{svnidlong} and passes them to
% \cs{svnidlong@readargs}. The normal argument braces are changed to category
% ``other'' and put into the macros parameter text to remove all code between
% them. This is done to avoid problems with comments direct after one of the
% arguments. Because the braces are now non-special the parentheses are made
% to a local replacement.
%
%    \begin{macrocode}
\begingroup
\catcode`\{=12\catcode`\}=12
\catcode`\(=1\catcode`\)=2
\gdef\svnidlong@readargsfull#1{#2}#3{#4}#5{#6}#7{#8}(%
 \svnidlong@readargs(#2)(#4)(#6)(#8)%
)
\endgroup
%    \end{macrocode}
% \end{macro}

% \begin{macro}{\svnidlong@readargs}
% Calls sub macro for all four arguments and ends the catcode changes made
% by \cs{svnidlong}.
%    \begin{macrocode}
\def\svnidlong@readargs#1#2#3#4{%
\svnkwsave@read #1\relax
\svnkwsave@read #2\relax
\svnkwsave@read #3\relax
\svnkwsave@read #4\relax
\endgroup
%    \end{macrocode}
% Now the update macros for date and id are called.
%    \begin{macrocode}
\ifx\svnkwLastChangedDate\empty
\else\@svn@scanlongdate{\svnkwLastChangedDate}\fi
\@svn@updateid{\svnkw{LastChangedRevision}}{\svnkw{LastChangedDate}}
{\svnkw{LastChangedBy}}%
\ignorespaces
}%
%    \end{macrocode}
% \end{macro}

% \subsection{KeyWord Macros}
% \begin{macro}{\svnkwsave}
% Save macro. Takes a dollar wrapped keyword string, reads it though
% \cs{svn@readkw} and saves it using \cs{svnkwdef}.
%    \begin{macrocode}
\def\svnkwsave{%
\begingroup 
\svn@catcodes
\svnkwsave@readargs
} 
%    \end{macrocode}
% \end{macro}

% \begin{macro}{\svnkwsave@readargs}
% Reads full argument, calls parse submacro and ends catcode changes.
% If \cs{svnkwsave} was called by \cs{svnid} scans the id keyword by calling the
% scan macro.
%    \begin{macrocode}
\gdef\svnkwsave@readargs#1{%
\svnkwsave@read#1\relax
\endgroup
\if@svnidsw
  \ifx\svnkwId\empty
  \else
    \expandafter
    \svn@scanId\svnkwId\relax
    \@svnidswfalse
  \fi
\fi
\ignorespaces
}
%    \end{macrocode}
% \end{macro}

% \begin{macro}{\svnkwsave@read}
% Reads the full keyword and strips the dollars.
%    \begin{macrocode}
\begingroup
\catcode`\$=12
\gdef\svnkwsave@read $#1$\relax{%
    \svn@checkcolon#1:\relax 
}
\endgroup
%    \end{macrocode}
% \end{macro}

% \begin{macro}{\svnkwsave@parse}
% Parse the keyword and save it away.
%    \begin{macrocode}
\begingroup
\catcode`\$=11
\gdef\svnkwsave@parse$#1:#2${%
\expandafter\xdef\csname svnkw#1\endcsname{#2}}
\endgroup
%    \end{macrocode}
% \end{macro}

% \begin{macro}{\svnkwdef}
% First we check if there is a `setter'-macro for the keyword called
% \cs{svnkwdef@}\meta{keyword}.
%    \begin{macrocode}
\newcommand{\svnkwdef}[2]{%
\@ifundefined{svnkwdef@#1}
%    \end{macrocode}
% If not we call the general macro \cs{svnkwdef@}.
%    \begin{macrocode}
{\svnkwdef@{#1}{#2}}
%    \end{macrocode}
% If yes we just call it with the value as argument.
%    \begin{macrocode}
{\csname svnkwdef@#1\endcsname{#2}}%
}
%    \end{macrocode}
% \end{macro}

% \begin{macro}{\svnkwdef@}
% This macro defines the second argument under \cs{svnkw}\meta{1st argument}.
% The |\xdef| is used to expand the content first (needed for internal use)
% and make the definition globally.
%    \begin{macrocode}
\newcommand{\svnkwdef@}[2]
{\expandafter\xdef\csname svnkw#1\endcsname{#2}}
%    \end{macrocode}
% Example: |\svnkwdef{Revision}{23}| will define |\svnkwRevision| as 23.
% \end{macro}

% \begin{macro}{\svnkwdef@Rev}
% \begin{macro}{\svnkwdef@Author}
% \begin{macro}{\svnkwdef@Date}
% `Setter'-macros for single keywords, used by \cs{svnkwdef}.\\
% These are needed to have have a common value for all alternative keyword
% names ala |Rev|, |Revision|, |LastChangedRevision|.
%
% The keywords |Rev|, |Author| and |Date|
% are just calling \cs{svnkwdef@} with a fixed first argument.
%    \begin{macrocode}
\def\svnkwdef@Rev#1{\svnkwdef@{Rev}{#1}}
\def\svnkwdef@Author#1{\svnkwdef@{Author}{#1}}
\def\svnkwdef@Date#1{\svnkwdef@{Date}{#1}}
%    \end{macrocode}
% The long keywords are defined then as aliases of the short,\\
% first for writing
%    \begin{macrocode}
\let\svnkwdef@Revision=\svnkwdef@Rev
\let\svnkwdef@LastChangedRevision=\svnkwdef@Rev
\let\svnkwdef@LastChangedBy=\svnkwdef@Author
\let\svnkwdef@LastChangedAt=\svnkwdef@Date
%    \end{macrocode}
% and then for reading.
%    \begin{macrocode}
\def\svnkwRevision{\svnkwRev}
\def\svnkwLastChangedRevision{\svnkwRev}
\def\svnkwLastChangedBy{\svnkwAuthor}
\def\svnkwLastChangedAt{\svnkwDate}
%    \end{macrocode}
% So \eg |\svnkw{LastChangedRevision}| is always be the
% same as |\svnkw{Rev}|.
% \end{macro}
% \end{macro}
% \end{macro}

% We define default values for normal keywords. Keyword |Filename| is the name
% given by |Id| and not a real keyword.
%    \begin{macrocode}
\svnkwdef{Rev}{0}
\svnkwdef{Date}{}
\svnkwdef{Author}{}
\svnkwdef{Filename}{}
\svnkwdef{HeadURL}{}
%    \end{macrocode}

% \begin{macro}{\svnkw}
% Macro to get keyword value. Just calls \cs{svnkw}\meta{ARGUMENT} where
% the argument interpreted as text. So \eg |\svnkw{Date}| is the same as
% |\svnkwDate| but this could be changed later so always use this interface
% to get the keyword values.
%
% \changes{v1.2}{2007/06/22}{Added warning when a wrong, maybe
% misspelled, keyword is given.}
%    \begin{macrocode}
\newcommand{\svnkw}[1]{%
\@ifundefined{svnkw#1}
{\PackageWarning{svn-multi}{SVN keyword '#1' not defined (typo?)}}
{\csname svnkw#1\endcsname}}%
%    \end{macrocode}
% \end{macro}
%

% \subsection{Keyword check and strip macros}
% The following macros are used to test whether the given keywords are fully
% expanded or not. 
% Subversion supports unexpanded keywords as input with or without colon and
% with or without trailing space(s), \ie a:~|$KW$|, b:~|$KW:$| or c:~|$KW: $|. 
% To avoid \LaTeX{} syntax errors in this pre-commit state the keyword is 
% checked by the following macros. Unexpanded keywords result in an empty value. 
% Also leading and trailing spaces are removed.
%
% \begin{macro}{\svn@checkcolon}
% Checks if the keyword contains a colon. It is called by \cs{svnkwsave@read} 
% with a trailing |:\relax| so that \#2 will be empty if there is no earlier 
% colon or will hold the value with this trailing colon otherwise. 
% The first case means that the keyword is unexpanded without colon (case a) 
% which leads to an empty value. In the second case \cs{svn@stripcolon} is 
% called to strip the colon and surrounding spaces. The final value is 
% returned by |\svn@value|.
%    \begin{macrocode}
\def\svn@checkcolon#1:#2\relax{%
    \def\svn@test{#2}%
    \ifx\svn@test\empty
    \svnkwdef{#1}{}%
    \else
      \svn@stripcolon#2\relax
      \svnkwdef{#1}{\svn@value}%
    \fi
}
%    \end{macrocode}
% \end{macro}

% \begin{macro}{\svn@stripcolon}
% Strips the previous added colon (for \cs{svn@checkcolon}).
% The remaining argument is checked if it's empty (case b) or only a space
% (case c). Otherwise the keyword is expanded and \cs{svn@stripspace} is
% called to strip the spaces.
%    \begin{macrocode}
\def\svn@stripcolon#1:\relax{%
    \def\svn@test{#1}%
    \ifx\svn@test\empty
      \gdef\svn@value{}%
    \else
    \ifx\svn@test\svn@spaceonly
      \gdef\svn@value{}%
    \else
     \svn@stripspace#1\relax\relax
    \fi\fi
}

\def\svn@spaceonly{ }
%    \end{macrocode}
% \end{macro}

% \begin{macro}{\svn@stripspace}
% Strips leading space if present and calls \cs{svn@striptrailingspace} to
% strip the trailing space.
%    \begin{macrocode}
\def\svn@stripspace#1#2\relax{%
    \def\svn@test{#1}%
    \ifx\svn@test\svn@spaceonly
      \gdef\svn@value{#2}%
    \else
      \svn@striptrailingspace#1#2\relax
    \fi
}
%    \end{macrocode}
% \end{macro}

% \begin{macro}{\svn@striptrailingspace}
% Strips trailing space using the macros parameter text. Must be called with
% |\relax| as end marker.
%    \begin{macrocode}
\def\svn@striptrailingspace#1 \relax{%
    \gdef\svn@value{#1}%
}
%    \end{macrocode}
% \end{macro}

% \subsection{Date Macros}
% \begin{macro}{\@svn@scandate}
% Scans data informations in Id keyword and saves them in macros.
%    \begin{macrocode}
\def\@svn@scandate#1{\@svn@scandate@#1\relax}

\def\@svn@scandate@#1-#2-#3 #4:#5:#6#7#8\relax{%
\gdef\svnfileyear{#1}%
\gdef\svnfilemonth{#2}%
\gdef\svnfileday{#3}%
\gdef\svnfilehour{#4}%
\gdef\svnfileminute{#5}%
\gdef\svnfilesecond{#6#7}%
\gdef\svnfiletimezone{+00}% #8 always 'Z' for Zulu-time (UTC)
}
%    \end{macrocode}
% \end{macro}

% \begin{macro}{\@svn@scanlongdate}
% Scans data informations in Date keyword and saves them in macros.
%    \begin{macrocode}
\def\@svn@scanlongdate#1{\expandafter\@svn@scanlongdate@#1\relax}
%
\def\@svn@scanlongdate@#1-#2-#3 #4:#5:#6 #700 #8\relax{%
\gdef\svnfileyear{#1}%
\gdef\svnfilemonth{#2}%
\gdef\svnfileday{#3}%
\gdef\svnfilehour{#4}%
\gdef\svnfileminute{#5}%
\gdef\svnfilesecond{#6}%
\gdef\svnfiletimezone{#7}%
}
%    \end{macrocode}
% \end{macro}

% \begin{macro}{\svnpdfdate}
% Returns date in a format needed for |\pdfinfo|.
%    \begin{macrocode}
\def\svnpdfdate{\svnyear\svnmonth\svnday
\svnhour\svnminute\svnsecond\svntimezone'00'}
%    \end{macrocode}
% \end{macro}

% \subsection{Mainfile Makros}
% \begin{macro}{\svnsetmainfile}
% Saves the current |HeadURL| and |Filename| keywords to macros.
% Will be called automatically in the preamble.
% \changes{v1.2}{2007/06/22}{New macro}
%    \begin{macrocode}
\newcommand{\svnsetmainfile}
{\edef\svnmainurl{\svnkw{HeadURL}}
\edef\svnmainfilename{\svnkw{Filename}}}
\AtBeginDocument{\svnsetmainfile}
%    \end{macrocode}
% \end{macro}

% \subsection{Register and FullName Macros}
% \begin{macro}{\svnRegisterAuthor}
% Saves the author's name by defining
% |\svn@author@|\meta{username} to it.
%    \begin{macrocode}
\newcommand{\svnRegisterAuthor}[2]{%
\expandafter\def\csname svn@author@#1\endcsname{#2}%
}
%    \end{macrocode}
% \end{macro}

% \begin{macro}{\svnFullAuthor}
% \begin{macro}{\svnFullAuthor*}
% We test if the starred or the normal version is used and call the
% appropriate submacro |\svnFullAuthor@star| or |\svnFullAuthor@normal|.
% \changes{v1.2}{2007/06/22}{Macro now returns the username if the full name
% was not registered.}
%    \begin{macrocode}
\newcommand{\svnFullAuthor}{%
\@ifnextchar{*}
{\svnFullAuthor@star}
{\svnFullAuthor@normal}
}
%    \end{macrocode}
% Both submacros are calling |\svnFullAuthor@| but with different arguments.
% The star macro also removes the star of course.
%    \begin{macrocode}
\def\svnFullAuthor@star*#1{\svnFullAuthor@{#1}{~(#1)}}
\def\svnFullAuthor@normal#1{\svnFullAuthor@{#1}{}}
%    \end{macrocode}
% |\svnFullAuthor@| now sets the author's full name. Note that |#2| is empty
% when the normal version is called.
%    \begin{macrocode}
\def\svnFullAuthor@#1#2{%
\@ifundefined{svn@author@#1}
{#1}
{\csname svn@author@#1\endcsname #2}%
}
%    \end{macrocode}
% \end{macro}
% \end{macro}

% \begin{macro}{\svnRegisterRevision}
% Saves the revision's name or tag by defining
% |\svn@revision@|\meta{revisionnumber} to it.
% \changes{v1.2}{2007/06/22}{New macro}
%    \begin{macrocode}
\newcommand{\svnRegisterRevision}[2]{%
\expandafter\def\csname svn@revision@#1\endcsname{#2}
}
%    \end{macrocode}
% \end{macro}

% \begin{macro}{\svnFullRevision}
% \begin{macro}{\svnFullRevision*}
% We test if the starred or the normal version is used and call the
% appropriate submacro |\svnFullRevision@star| or |\svnFullRevision@normal|.
% \changes{v1.2}{2007/06/22}{New macro}
%    \begin{macrocode}
\newcommand{\svnFullRevision}{%
\@ifnextchar{*}
{\svnFullRevision@star}
{\svnFullRevision@normal}
}
%    \end{macrocode}
% Both submacros are calling |\svnFullRevision@| but with different arguments.
% The star macro also removes the star of course.
%    \begin{macrocode}
\def\svnFullRevision@star*#1{\svnFullRevision@{#1}{~(r#1)}}
\def\svnFullRevision@normal#1{\svnFullRevision@{#1}{}}
%    \end{macrocode}
% |\svnFullRevision@| now sets the revision name. Note that |#2| is empty
% when the normal version is called.
%    \begin{macrocode}
\def\svnFullRevision@#1#2{%
\@ifundefined{svn@revision@#1}
{Revision #1}
{\csname svn@revision@#1\endcsname #2}%
}
%    \end{macrocode}
% \end{macro}
% \end{macro}

% \begin{macro}{\svnnolinkurl}
% This code is taken from the |hyperref| package and is the definition of
% |\url| just without the part which creates the actual hyperlink. This needs
% of course the |hyperref| package. A warning is given if it isn't loaded.
% \changes{v1.2}{2007/06/22}{New macro}
%    \begin{macrocode}
    \DeclareRobustCommand*{\svnnolinkurl}{%
        \@ifundefined{hyper@normalise}
        {\PackageWarning{svn-multi}{Package hyperref is needed for \noexpand
        \svnnolinkurl.}}
        {\hyper@normalise\svnnolinkurl@}}%
    \def\svnnolinkurl@#1{\Hurl{#1}}
%    \end{macrocode}
% \end{macro}

% \subsection{Auxiliary file generation and read-back}
% At the end of document we write the values to an auxiliary file.
%    \begin{macrocode}
\AtEndDocument{%
%    \end{macrocode}
% We first check if we have something to save. Revision, date and author must be
% non-empty. This suppresses the auxiliary file if the user doesn't use the
% appropriate macros but other provided by this package.
%    \begin{macrocode}
 \if@filesw
 \ifx\@svn@rev\empty\else
 \ifnum\@svn@rev=0\else
 \ifx\@svn@date\empty\else
 \ifx\@svn@author\empty\else
%    \end{macrocode}
% Open outfile to write project keywords.
%    \begin{macrocode}
 \newwrite\svn@write
 \immediate\openout\svn@write=\jobname.svn
 \immediate\write\svn@write{%
 \@percentchar\space SVN cache^^J%
 \noexpand\def\noexpand\svnrev{\@svn@rev}^^J%
 \noexpand\def\noexpand\svndate{\@svn@date}^^J%
 \noexpand\def\noexpand\svnauthor{\@svn@author}^^J%
 \noexpand\def\noexpand\svnyear{\@svn@year}^^J%
 \noexpand\def\noexpand\svnmonth{\@svn@month}^^J%
 \noexpand\def\noexpand\svnday{\@svn@day}^^J%
 \noexpand\def\noexpand\svnhour{\@svn@hour}^^J%
 \noexpand\def\noexpand\svnminute{\@svn@minute}^^J%
 \noexpand\def\noexpand\svnsecond{\@svn@second}^^J%
 \noexpand\def\noexpand\svntimezone{\@svn@timezone}^^J%
 }
 \immediate\closeout\svn@write%
 \fi\fi\fi\fi\fi%
}

%    \end{macrocode}
% Reread output from last compile run if it exists.
%    \begin{macrocode}
\InputIfFileExists{\jobname.svn}{}{}
%    \end{macrocode}
%
% \Finale
\endinput

